﻿/*
 * Created by SharpDevelop.
 * User: Intel
 * Date: 18.11.2014
 * Time: 14:57
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
namespace Region
{
  /// <summary>
  /// Description of DBList.
  /// </summary>
  public class DBList<Line> where Line : new()
  {
    protected readonly Engine m_engine;
    protected List<Line> m_lines;
    protected Dictionary<String, Object> m_wheres;
    public Line getLine(Int32 l) { return this.m_lines[l]; }
    public Int32 NumLines { get { return m_lines.Count; } }
    protected Int32 m_FullLines;
    public Int32 FullLines { get { return m_FullLines; } }
    protected List<String> DefaultTables = new List<String>();
    protected List<String> DefaultPoles = new List<String>();
    protected List<String> DefaultOrderBy = new List<String>();    
    public DBList(Engine engine)
    {
      m_engine = engine;
      m_lines = new List<Line>();
      m_wheres = new Dictionary<String, Object>();      
    }
    public bool clearWhere()
    {
      m_wheres = new Dictionary<String, Object>();
      return true;
    }
    public bool setWhere(String Where, Object Value)
    {
        if (Value==null)
           if (m_wheres.ContainsKey(Where)) 
           {
               m_wheres.Remove(Where);
               return true;
           }       
      m_wheres[Where] = Value;
      return true;
    }
    public Object getWhere(String Where)
    {
        if (m_wheres.ContainsKey(Where)) 
            return m_wheres[Where];
        return null;
    }
      protected virtual void ProceessWheres(SQLParam Params,List<String> Tables, List<String> Poles,List<String> Wheres,List<String> OrderBy)
    {
      
    } 
    protected virtual Line readLine(Dictionary<String, Object> r)
    {
      return new Line();
    }
    public virtual bool Filter()
    {
      var Tables = new List<String>(DefaultTables);
      var Poles = new List<String>(DefaultPoles);
      var Wheres = new List<String>();
      var OrderBy = new List<String>(DefaultOrderBy);
      var Params = new SQLParam();
      Wheres.Add("1");
      ProceessWheres(Params, Tables, Poles, Wheres, OrderBy);
      String OrderBySQL = "";
      String LimitSQL = "";      
      
      Int32 LineInPage, Page;
      if (!(m_wheres.ContainsKey("IgnorePage") && (Boolean)m_wheres["IgnorePage"]))
        if (m_wheres.ContainsKey("LineInPage") && m_wheres["LineInPage"] != null && Int32.TryParse(m_wheres["LineInPage"].ToString(), out LineInPage) && LineInPage > 1)
      {
        if (!m_wheres.ContainsKey("Page") || m_wheres["Page"] == null || !Int32.TryParse(m_wheres["Page"].ToString(), out Page)) Page = 1;
        Int32 Start = (Page - 1) * LineInPage;
        LimitSQL = "LIMIT " + Start + ", " + LineInPage + " ";
      }

      if (OrderBy.Count > 0) OrderBySQL = "ORDER BY " + String.Join(", ", OrderBy.ToArray());
      String SQL = String.Format("SELECT SQL_CALC_FOUND_ROWS {0} FROM {1} WHERE ({2}) {3} {4}",
          String.Join(", ", Poles.ToArray()),
          String.Join(" ", Tables.ToArray()),
          String.Join(") AND (", Wheres.ToArray()),
          OrderBySQL, LimitSQL);
      SQLResult r = m_engine.SQLSelect(SQL,Params);
      SQLResult r2 = m_engine.SQLSelect("SELECT FOUND_ROWS() AS Count",new SQLParam());                        
      m_FullLines = (Int32)(Int64)r2[0]["Count"];
      m_lines.Clear();
      for (Int32 i = 0; i < r.Count; i++)            
      {
        m_lines.Add(readLine(r[i]));
      }
      return true;
    }
    protected virtual Boolean preLoadObject<T>(Dictionary<String,Object> Fields,Object PkValue)
        where T : DBObject
    {
        return false;
    }
    protected virtual SQLResult preLoadFields<T>()
    {        
        var Tables = new List<String>(DefaultTables);
        var Poles = new List<String>(DefaultPoles);
        var Wheres = new List<String>();
        var OrderBy = new List<String>(DefaultOrderBy);
        var Params = new SQLParam();
        Wheres.Add("1");
        ProceessWheres(Params, Tables, Poles, Wheres, OrderBy);
        String SQL = String.Format("SELECT {0} FROM {1} WHERE ({2})",
          String.Join(", ", Poles.ToArray()),
          String.Join(" ", Tables.ToArray()),
          String.Join(") AND (", Wheres.ToArray()));
        return m_engine.SQLSelect(SQL, Params);
    }
    public virtual Boolean preLoad<T>(Dictionary<Int32,Dictionary<String,Object>> Fields = null)        
        where T: DBObject
    {
        var att = typeof(T).GetCustomAttributes(typeof(DBObjectAttribute), true);
        if (att.Length == 0)
            return false;
        var ColAtt = (DBObjectAttribute)att[0];
        if (ColAtt.PrimaryKeyPole == null)
            return false;
        String PrimaryKeyPole = ColAtt.PrimaryKeyPole;        
        if (Fields == null)
            Fields = preLoadFields<T>();
        if (Fields == null)
            return false;
        for (Int32 i = 0; i < Fields.Count; i++)
            if (!preLoadObject<T>(Fields[i], Fields[i][PrimaryKeyPole]))
                return false;
        return true;
    }
  }
}
